package com.game1;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.*;

import javax.swing.*;


public class Flappybell extends JFrame implements ActionListener{
	
	gamePanel gp = null;
	gamePanel regp = null;
	startgamePanel sgp = null;
	JMenuBar jmb = null;
	JMenu jm = null;
	JMenuItem jmi1 = null;
	JMenuItem jmi2 = null;
	JMenuItem jmi3 = null;
	
	public static void main(String[] args){
		
		Flappybell t = new Flappybell();
		
	}

	public Flappybell()
	{
		sgp = new startgamePanel();
		this.add(sgp);
		Thread t = new Thread(sgp);
		t.start();
		
		jmb = new JMenuBar();
		jm = new JMenu("游戏");
		jmi1 = new JMenuItem("开始游戏");
		jmi2 = new JMenuItem("重新开始");
		jmi3 = new JMenuItem("退出");
		
		jmb.add(jm);
		jm.add(jmi1);
		jm.add(jmi2);
		jm.add(jmi3);
		
		jmi1.addActionListener(this);
		jmi1.setActionCommand("start");
		jmi2.addActionListener(this);
		jmi2.setActionCommand("restart");
		jmi3.addActionListener(this);
		jmi3.setActionCommand("quit");
		
		this.setJMenuBar(jmb);
		this.setTitle("Flappybell");
		this.setSize(700, 600);
		this.setLocation(200, 100);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
	
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		
		if(e.getActionCommand().equals("start"))
		{
			gp = new gamePanel();
			
			this.remove(sgp);
			this.add(gp);
			
			Thread t= new Thread(gp);
			t.start();
			this.addKeyListener(gp);
			this.setVisible(true);
		}else if(e.getActionCommand().equals("restart"))
		{
			if(regp != null)
			{
				this.remove(regp);
			}
	
			regp = new gamePanel();
			
			gp.isLive = false;
			this.remove(gp);
			this.add(regp);
			
			Thread t = new Thread(regp);
			t.start();
			this.addKeyListener(regp);
			this.setVisible(true);
		}else if(e.getActionCommand().equals("quit"))
		{
			System.exit(0);
		}
		
	}
	
}

class gamePanel extends JPanel implements KeyListener, Runnable{
	
	Bell b = null;
	Random rand = new Random();
	ArrayList<Obstacle> al = new ArrayList<Obstacle>();
	int alSize = 999;
	boolean isLive = true;
	
	public gamePanel()
	{
		b = new Bell(100);
		
		for(int i = 0; i < alSize; i++)
		{
			int distent = rand.nextInt(21)+60;
			int owidth = 45;
			int oheight = rand.nextInt(151)+150;
			if(i == 0 || i%2 ==0)
			{
				Obstacle ob = new Obstacle(700+i*75, 0);
				ob.setHeight(oheight);
				ob.setWidth(owidth);
				al.add(ob);
			}
			else
			{
				Obstacle ob = new Obstacle(700+(i-1)*75, al.get(i-1).height+distent);
				ob.setHeight(oheight+100);
				ob.setWidth(owidth);
				al.add(ob);
				owidth = rand.nextInt(16)+30;
			}
		}
	}
	
	public void paint(Graphics g)
	{
		super.paint(g);
		
		this.drawBell(g, this.b.x, this.b.y);
		g.fillRect(0, 450, 700, 150);
		
		
		for(int i = 0; i < alSize; i++)
		{
			Obstacle ob = al.get(i);
			
			g.fillRect(ob.x, ob.y, ob.width, ob.height);
		}
		
		this.showScore(g);
		
	}

	public void drawBell(Graphics g, int x, int y)
	{
		g.fillOval(x, y, 30, 30);
	}
	
	public void Touch(Bell b, Obstacle o)
	{
		if(o.y == 0)
		{
			if(b.y < o.y+o.height && b.x+30 > o.x && b.x < o.x-30)
			{
				b.isLive = false;
			}
			if(b.x+30 > o.x && b.x < o.x+o.width && b.y < o.y+o.height)
			{
				b.isLive = false;
			}
		}
		else
		{
			if(b.y+30 > o.y && b.x+30 > o.x)
			{
				b.isLive = false;
			}
			if(b.y > o.y && b.x+30 > o.x && b.x < o.x+o.width)
			{
				b.isLive = false;
			}
		}
	}
	
	public void showScore(Graphics g)
	{
		g.setColor(Color.white);
		g.setFont(new Font("宋体", Font.BOLD, 50));
		g.drawString((700-al.get(0).x)+"", 300, 500);
	}
	
	
	@Override
	public void keyPressed(KeyEvent e) {
		
		if(e.getKeyCode() == KeyEvent.VK_UP)
		{
			this.b.moveUp();
		}
		
		this.repaint();
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void run() {
		
		while(true)
		{
			try {
				Thread.sleep(25);
			} catch (Exception e) {
				// TODO: handle exception
			}
			
			this.b.moveDown();
			
			if((this.b.y+30 >= 450 || !this.b.isLive) && this.isLive)
			{
				break;
			}
			
			for(int i = 0; i < alSize; i++)
			{
				Obstacle ob = al.get(i);
				
				ob.Move();
			}
			
			for(int i = 0; i < alSize; i++)
			{
				Obstacle ob = al.get(i);
				
				this.Touch(this.b, ob);
			}
			
			
			
			this.repaint();
		}
		
	}
	
	public boolean GameOver()
	{
		return !this.b.isLive;
	}


}

class startgamePanel extends JPanel implements Runnable{
	
	int times = 0;
	
	public void paint(Graphics g)
	{
		super.paint(g);
		
		if(times%2 == 0)
		{
			Font f = new Font("华文彩云", Font.BOLD, 50);
			g.setFont(f);
			g.drawString("Flappy Bell", 200, 200);
		}
	}

	@Override
	public void run() {
		
		while(true)
		{
			try {
				Thread.sleep(750);
			} catch (Exception e) {
				// TODO: handle exception
			}
			
			times++;
			this.repaint();
		}
		
	}
	
}

class Bell{
	
	int y;
	final int x = 200;
	boolean isLive = true;
	
	public void moveUp()
	{
		if(y > 0 && isLive)
		{
			y -= 15;
		}
	}
	
	public void moveDown()
	{
		if(y < 600)
		{
			y += 1;
		}
	}
	
	public Bell(int y)
	{
		this.y = y;
	}
}

class Obstacle{
	
	int x;
	int y;
	boolean isOver = false;
	
	int height;
	int width;
	
	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public Obstacle(int x, int y)
	{
		this.x = x;
		this.y = y;
	}
	
	public void Move()
	{
		x -= 1;
	}
}


